package com.gaogzhen.jucCollections;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.HashMap;

/**
 * @author Administrator
 * @date 2023-01-07 08:40
 */
public class Test01 {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
//        int x = 9;
//        System.out.println(tableSizeFor(x));
//        test01();
//        testHashMapResize();
//        System.out.println((long) 1/0.75f);
//        System.out.println(-5>>1);
//        testScale();
        aUnsafe();
    }

    public static void aUnsafe() throws NoSuchFieldException, IllegalAccessException {
        Class<Unsafe> clazz = Unsafe.class;
        Field unsafeField = clazz.getDeclaredField("theUnsafe");
        unsafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe)unsafeField.get(null);

        int[] temp = {1, 2, 3};
        int base = unsafe.arrayBaseOffset(int[].class);
        int scale = unsafe.arrayIndexScale(int[].class);
        // 方式一
        for (int i = 0; i < temp.length; i++) {
            System.out.println(unsafe.getInt(temp, ((long) i * scale) + base));
        }
        // 方式二
//        int shift = 31 - Integer.numberOfLeadingZeros(scale);
//        for (int i = 0; i < temp.length; i++) {
//            System.out.println(unsafe.getInt(temp, ((long) i << shift) + base));
//        }
    }

    public static void testScale() throws NoSuchFieldException, IllegalAccessException {
        Class<Unsafe> clazz = Unsafe.class;
        Field unsafeField = clazz.getDeclaredField("theUnsafe");
        unsafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe)unsafeField.get(null);
        TestScale[] t = new TestScale[10];
        Class<TestScale[]> tc = TestScale[].class;
//        System.out.println(unsafe.arrayBaseOffset(tc));
        System.out.println(unsafe.arrayIndexScale(long[].class));
        System.out.println(unsafe.arrayIndexScale(Long[].class));
        System.out.println(unsafe.arrayIndexScale(tc));
        System.out.println(unsafe.arrayIndexScale(Object[].class));
    }

    public static void testHashMapResize() {
        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(1, null);
        map.put(2, null);
        map.put(3, null);
        map.put(4, null);
        map.put(5, null);
        map.put(6, null);
        map.put(7, null);
        map.put(8, null);
        map.put(9, null);
        map.put(10, null);
        map.put(16, null);
        map.put(11, null);

        map.put(12, null);
    }

    public static void test01() {
//        int[] a = {1, 2, 3 };
//        Unsafe unsafe = Unsafe.getUnsafe();
        System.out.println(Unsafe.ARRAY_LONG_INDEX_SCALE);
    }
    private static final int tableSizeFor(int c) {
        int MAXIMUM_CAPACITY = 1 << 30;
        int n = c - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }
}
